package com.pxmeta.chat.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.pxmeta.chat.entity.ChatGroup;
import com.pxmeta.chat.entity.vo.ChatGroupDetailVO;
import com.pxmeta.chat.entity.vo.ChatGroupListVO;
import com.pxmeta.chat.entity.vo.ChatGroupUserVO;
import com.pxmeta.chat.entity.vo.CreateGroupVO;
import com.pxmeta.chat.mapper.ChatGroupMapper;
import com.pxmeta.chat.service.HuanxinService;
import com.pxmeta.chat.service.IChatGroupService;
import com.pxmeta.circle.entity.Circle;
import com.pxmeta.circle.service.ICircleService;
import com.pxmeta.common.enums.CircleUserLevelEnum;
import com.pxmeta.user.entity.User;
import com.pxmeta.user.entity.UserDisturb;
import com.pxmeta.user.service.IUserDisturbService;
import com.pxmeta.user.service.IUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.avro.data.Json;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class ChatGroupServiceImpl extends ServiceImpl<ChatGroupMapper,ChatGroup> implements IChatGroupService {

    private final HuanxinService huanxinService;
    private final IUserService userService;
    private final IUserDisturbService userDisturbService;
    private final ICircleService circleService;


    @Override
    public String createChatGroups(Long userId, CreateGroupVO vo) {
        String groupid = vo.getChatGroupId();
        ChatGroup chatGroup = new ChatGroup();
        chatGroup.setUserCount(1);
        chatGroup.setId(groupid);
        chatGroup.setMembersOnly(false);
        chatGroup.setGroupName(vo.getGroupName());
        chatGroup.setAvatar(vo.getAvatar());
        chatGroup.setDescription(vo.getDescription());
        chatGroup.setCircleId(vo.getCircleId());
        chatGroup.setOwnerId(userId);
        this.save(chatGroup);
        return groupid;
    }

    @Override
    public List<ChatGroupListVO> getCircleChatGroups(Long circleId, Long userId, String name) {
        List<String> groupIds = getUserGroupIdList(userId);
        LambdaQueryWrapper<ChatGroup> wrapper = Wrappers.lambdaQuery();

        if (StringUtils.isNotBlank(name)){
            wrapper.like(ChatGroup::getGroupName,name);
        }
        if (circleId != 1){
            wrapper.eq(ChatGroup::getCircleId,circleId);
        }
        wrapper.eq(ChatGroup::getIsPublic,true);
        if (CollectionUtil.isNotEmpty(groupIds)){
            wrapper.notIn(ChatGroup::getId,groupIds);
        }
        wrapper.orderByDesc(ChatGroup::getUserCount,ChatGroup::getCreateTime)
                .last("limit 5");

        List<ChatGroup> list = this.list(wrapper);

        return list.stream().map(l -> {
            Integer userCount = l.getUserCount();
            List<String> tags = Lists.newLinkedList();
            tags.add(userCount + "人");
            ChatGroupListVO vo = new ChatGroupListVO();
            vo.setChatGroupId(l.getId());
            vo.setAvatar(l.getAvatar());
            Boolean membersOnly = l.getMembersOnly();

            if(membersOnly){
                vo.setAddType(2);//加入
            }else {
                vo.setAddType(1);//申请
            }
            vo.setName(l.getGroupName());
            vo.setDesc(l.getDescription());
            vo.setTags(tags);
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<ChatGroupListVO> getChatGroupPage(Long circleId, Long userId, String keyword, Integer page, Integer size) {
        List<String> userGroupIds = getUserGroupIdList(userId);
        LambdaQueryWrapper<ChatGroup> wrapper = Wrappers.lambdaQuery();
        if (StringUtils.isNotBlank(keyword)){
            wrapper.like(ChatGroup::getGroupName,keyword);
        }
        if (circleId != 1){
            wrapper.eq(ChatGroup::getCircleId,circleId);
        }
        wrapper.eq(ChatGroup::getIsPublic,true)
                .orderByDesc(ChatGroup::getUserCount);
        List<ChatGroup> list = this.page(new Page<>(page,size),wrapper).getRecords();
        return list.stream().map(l -> {
            Integer userCount = l.getUserCount();
            List<String> tags = Lists.newLinkedList();
            tags.add(userCount + "人");
            ChatGroupListVO vo = new ChatGroupListVO();
            vo.setChatGroupId(l.getId());
            vo.setAvatar(l.getAvatar());
            Boolean membersOnly = l.getMembersOnly();

            if(membersOnly){
                vo.setAddType(2);//加入
            }else {
                vo.setAddType(1);//申请
            }

            if (userGroupIds.contains(l.getId())){
                vo.setAddType(3); //已加入
            }
            vo.setName(l.getGroupName());
            vo.setDesc(l.getDescription());
            vo.setTags(tags);
            return vo;
        }).collect(Collectors.toList());
    }



    private List<String> getUserGroupIdList(Long userId){
        String username = userService.getById(userId).getUsername();
        JSONArray userChatGroups = huanxinService.getUserChatGroups(username);
        return userChatGroups.stream().map(obj->{
            JSONObject jsonObject = JSON.parseObject(JSONObject.toJSONString(obj));
            return jsonObject.getString("groupid");
        }).collect(Collectors.toList());
    }

    /**
     * 获取用户屏蔽的群聊列表
     * @param userId
     * @return
     */
    @Override
    public List<Long> getNotDisturbChatGroups(Long userId) {
        LambdaQueryWrapper<UserDisturb> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(UserDisturb::getUserId, userId)
                .eq(UserDisturb::getTargetType, 1);
        return userDisturbService.list(wrapper).stream().map(UserDisturb::getTargetId).collect(Collectors.toList());
    }

    @Override
    public ChatGroupDetailVO getChatGroupInfo(Long chatGroupId,String username) {
        ChatGroup chatGroup = this.getById(chatGroupId);
        Circle circle = circleService.getById(chatGroup.getCircleId());
        JSONArray chatGroupAdmin = huanxinService.getChatGroupAdmin(chatGroupId.toString());
        List<String> usernameList = chatGroupAdmin.stream().map(JSONObject::toJSONString).collect(Collectors.toList());
        List<ChatGroupUserVO> userList = Lists.newLinkedList();
        if (!usernameList.isEmpty()){
            LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
            wrapper.in(User::getUsername,usernameList);
            userList = userService.list(wrapper).stream().map(u -> {
                ChatGroupUserVO userVo = new ChatGroupUserVO();
                userVo.setUserId(u.getId());
                userVo.setImUserId(u.getUsername());
                userVo.setLevel(CircleUserLevelEnum.ADMIN.getLevel());
                userVo.setNickname(u.getNickname());
                userVo.setAvatar(u.getAvatar());
                return userVo;
            }).collect(Collectors.toList());
        }

        Long ownerId = chatGroup.getOwnerId();
        User owner = userService.getById(ownerId);
        ChatGroupUserVO ownerVO = new ChatGroupUserVO();
        ownerVO.setNickname(owner.getNickname());
        ownerVO.setLevel(CircleUserLevelEnum.CREATOR.getLevel());
        ownerVO.setUserId(ownerId);
        ownerVO.setAvatar(owner.getAvatar());
        ownerVO.setImUserId(owner.getUsername());
        userList.add(0,ownerVO);
        JSONArray userChatGroups = huanxinService.getUserChatGroups(username);

        Integer addType = 1;
        Boolean membersOnly = chatGroup.getMembersOnly();
        if(membersOnly){
            addType = 2;
        }
        List<String> groupIds = userChatGroups.stream().map(obj->{
            JSONObject jsonObject = JSON.parseObject(JSONObject.toJSONString(obj));
            return jsonObject.getString("groupid");
        }).collect(Collectors.toList());
        if (groupIds.contains(chatGroupId.toString())){
            addType = 3;
        }

        return ChatGroupDetailVO.builder().chatGroupAvatar(chatGroup.getAvatar())
                .chatGroupName(chatGroup.getGroupName())
                .description(chatGroup.getDescription())
                .maxUserCount(chatGroup.getMaxusers())
                .currentUserCount(chatGroup.getUserCount())
                .circleName(circle.getName())
                .circleId(circle.getId())
                .adminUsers(userList)
                .remindOnlyAdmin(chatGroup.getRemindOnlyAdmin())
                .membersOnly(chatGroup.getMembersOnly())
                .id(chatGroupId)
                .addType(addType)
                .build();
    }

    @Override
    public void deleteChatGroup(String groupId) {
        huanxinService.deleteChatGroup(groupId);
        this.removeById(groupId);
    }

    @Override
    public void increaseUserCount(String groupId, int size) {
        ChatGroup group = this.getById(groupId);
        Integer userCount = group.getUserCount();
        userCount += size;
        ChatGroup chatGroup = new ChatGroup();
        chatGroup.setId(groupId);
        chatGroup.setUserCount(userCount);
        this.updateById(chatGroup);
    }

    @Override
    public void signOutChatGroup(String groupId, String username) {
        huanxinService.removeUserByChatGroups(groupId, username);
        ChatGroup chatGroup = this.getById(groupId);
        Integer userCount = chatGroup.getUserCount();
        userCount --;
        ChatGroup newChatGroup = new ChatGroup();
        newChatGroup.setId(groupId);
        newChatGroup.setUserCount(userCount);
        this.updateById(newChatGroup);
    }
}
